<template>
  <div class='absolute inset-0 z-10 rounded-2xl pt-10' :style="{backgroundColor: 'rgba(16, 24, 40, 0.20)'}">
      <div class='flex h-full flex-col rounded-2xl bg-white'>
        <div class='flex h-8 shrink-0 items-center justify-between pl-4 pr-3 pt-3'>
          <div class='truncate text-base font-semibold text-gray-900'>
            测试运行 {{nodeName}}
          </div>
          <div clas='ml-2 shrink-0 cursor-pointer p-1' @click="() => {
            onHide()
          }">
            <RiCloseLine class='h-4 w-4 text-gray-500 ' />
          </div>
        </div>
        <div v-if="showSpecialResultPanel" class='h-0 grow overflow-y-auto pb-4'>
          <SpecialResultPanel />
        </div>
        <div v-if="!showSpecialResultPanel" class='h-0 grow overflow-y-auto pb-4'>
          <div class='mt-3 space-y-4 px-4'>
              <div v-for="(form, index) in form" :key="index">
                <Form
                  :key="index"
                  :class="cn(index < forms.length - 1 && 'mb-4')"
                  :label="form.label" :inputs="form.inputs" :values="form.values"  :onChange="form.onChange"
                />
                <Split v-if="index < forms.length - 1 "/>
              </div>
          </div>
          <div class='mt-4 flex justify-between space-x-2 px-4' >
              <div
                v-if="isRunning "
                class='cursor-pointer rounded-lg border border-gray-200 bg-white p-2 shadow-xs'
                @click="onStop"
              >
                <StopCircle class='h-4 w-4 text-gray-500' />
              </div>
            <Button :disabled="!isFileLoaded || isRunning" type='primary' class='w-0 grow space-x-2' @click="handleRun">
              <RiLoader2Line v-if="isRunning" class='h-4 w-4 animate-spin text-white' />
              <div>{{isRunning ? '运行中':'开始运行'}}</div>
            </Button>
          </div>
            <ResultPanel v-if="isRunning" status='running' :showSteps="false" />
            <span v-if="isFinished">
              <template #result></template>
            </span>
            
        </div>
      </div>
  </div>
</template>
<script setup lang="ts" name="BeforeRunForm">
import {
  RiCloseLine,
  RiLoader2Line,
} from '@remixicon/vue'
import type { Props as FormProps } from './form.vue'
import Form from './form.vue'
import cn from '@/utils/classnames'
import Button from '@/app/components/base/button'
import { StopCircle } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices'
import Split from '@/app/components/workflow/nodes/_base/components/split'
import { InputVarType, NodeRunningStatus } from '@/app/components/workflow/types'
import ResultPanel from '@/app/components/workflow/run/result-panel'
import Toast from '@/app/components/base/toast'
import { TransferMethod } from '@/types/app'
import { getProcessedFiles } from '@/app/components/base/file-uploader/utils'
import type { BlockEnum } from '@/app/components/workflow/types'
import type { Emoji } from '@/app/components/tools/types'
import type { SpecialResultPanelProps } from '@/app/components/workflow/run/special-result-panel'
import SpecialResultPanel from '@/app/components/workflow/run/special-result-panel'
import { computed } from 'vue'
import { message } from 'ant-design-vue'

type BeforeRunFormProps = {
  nodeName: string
  nodeType?: BlockEnum
  toolIcon?: string | Emoji
  onHide: () => void
  onRun: (submitData: Record<string, any>) => void
  onStop: () => void
  runningStatus: NodeRunningStatus
  forms: FormProps[]
  showSpecialResultPanel?: boolean
} & Partial<SpecialResultPanelProps>

function formatValue(value: string | any, type: InputVarType) {
  if (type === InputVarType.number)
    return Number.parseFloat(value)
  if (type === InputVarType.json)
    return JSON.parse(value)
  if (type === InputVarType.contexts) {
    return value.map((item: any) => {
      return JSON.parse(item)
    })
  }
  if (type === InputVarType.multiFiles)
    return getProcessedFiles(value)

  if (type === InputVarType.singleFile) {
    if (Array.isArray(value))
      return getProcessedFiles(value)
    return getProcessedFiles([value])[0]
  }

  return value
}

const props = defineProps<BeforeRunFormProps>();

  const isFinished = computed(()=> props.runningStatus === NodeRunningStatus.Succeeded || props.runningStatus === NodeRunningStatus.Failed || props.runningStatus === NodeRunningStatus.Exception) 
  const isRunning = computed(()=> props.runningStatus === NodeRunningStatus.Running)
  const isFileLoaded =computed(() => {
    // system files
    const filesForm = props.forms.find(item => !!item.values['#files#'])
    if (!filesForm)
      return true

    const files = filesForm.values['#files#'] as any
    if (files?.some((item: any) => item.transfer_method === TransferMethod.local_file && !item.upload_file_id))
      return false
    return true
  })
  const handleRun = () => {
    let errMsg = ''
    props.forms.forEach((form) => {
      form.inputs.forEach((input) => {
        const value = form.values[input.variable] as any
        if (!errMsg && input.required && (value === '' || value === undefined || value === null || (input.type === InputVarType.files && value.length === 0)))
          errMsg = `${typeof input.label === 'object' ? input.label.variable : input.label } 不能为空 `

        if (!errMsg && (input.type === InputVarType.singleFile || input.type === InputVarType.multiFiles) && value) {
          let fileIsUploading = false
          if (Array.isArray(value))
            fileIsUploading = value.find(item => item.transferMethod === TransferMethod.local_file && !item.uploadedId)
          else
            fileIsUploading = value.transferMethod === TransferMethod.local_file && !value.uploadedId

          if (fileIsUploading)
            errMsg = "请等待文件上传完成"
        }
      })
    })
    if (errMsg) {
      message.error(errMsg)
      return
    }

    const submitData: Record<string, any> = {}
    let parseErrorJsonField = ''
    props.forms.forEach((form) => {
      form.inputs.forEach((input) => {
        try {
          const value = formatValue(form.values[input.variable], input.type)
          submitData[input.variable] = value
        }
        catch (e) {
          parseErrorJsonField = input.variable
        }
      })
    })
    if (parseErrorJsonField) {
      message.error(`${parseErrorJsonField} 是非法的 JSON`)
      return
    }

    props.onRun(submitData)
  }

  </script>

